package top.cardone.beans;

import com.google.common.base.Charsets;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.io.Resource;
import top.cardone.context.ApplicationContextHolder;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * json 文件解析为对象
 * Created by yao hai tao on 2015/5/22.
 */
public class JsonFileFactoryBean implements FactoryBean<Object> {
	@lombok.Setter
	private Resource jsonFile;

	@lombok.Setter
	private Resource[] jsonFiles;

	@lombok.Setter
	@lombok.Getter
	private Class<?> objectType;

	@lombok.Setter
	@lombok.Getter
	private boolean singleton;

	private Object object;

	private Object getObjectForJsonFiles() throws Exception {
		if (ArrayUtils.isEmpty(jsonFiles)) {
			return null;
		}

		Map<String, Object> map = Maps.newHashMap();

		for (Resource jsonFile : jsonFiles) {
			if (!jsonFile.exists()) {
				continue;
			}

			String json = FileUtils.readFileToString(jsonFile.getFile(), Charsets.UTF_8);

			Map<String, Object> itemMap = ApplicationContextHolder.getBean(Gson.class).fromJson(json, new TypeToken<LinkedHashMap<String, Object>>() {
			}.getType());

			if (MapUtils.isNotEmpty(itemMap)) {
				map.putAll(itemMap);
			}
		}

		if (objectType == null || Map.class.equals(objectType)) {
			object = map;
		} else {
			String json = ApplicationContextHolder.getBean(Gson.class).toJson(map);

			object = ApplicationContextHolder.getBean(Gson.class).fromJson(json, objectType);
		}

		return object;
	}

	@Override
	public Object getObject() throws Exception {
		if (jsonFile == null) {
			return this.getObjectForJsonFiles();
		}

		if (BooleanUtils.isTrue(singleton) && object != null) {
			return object;
		}

		if (!jsonFile.exists()) {
			return this.getObjectForJsonFiles();
		}

		String json = FileUtils.readFileToString(jsonFile.getFile(), Charsets.UTF_8);

		if (objectType == null) {
			object = ApplicationContextHolder.getBean(Gson.class).fromJson(json, new TypeToken<LinkedHashMap<String, Object>>() {
			}.getType());
		} else {
			object = ApplicationContextHolder.getBean(Gson.class).fromJson(json, objectType);
		}

		return object;
	}
}
